import numpy as np
import matplotlib
import matplotlib.pyplot as plt
import matplotlib.animation as animation
import copy
import math

# 指定渲染环境
# %matplotlib notebook
# %matplotlib inline

SZ = 51
dx = [0,1,0,-1,1,-1,1,-1]
dy = [1,0,-1,0,1,-1,-1,1]

def inblock(x,y):
    if SZ - 10 <= x and x <= SZ-5 and SZ - 10 <= y and y <= SZ-5:
        return 1
    if (x-5)*(x-5) + (y-15)*(y-15) <= 16:
        return 1
    return 0

def update_points(num):
    '''
    更新数据点
    '''
    x1 = []
    y1 = []
    # print('col = ',col)
    for i in range(len(X)):
        for j in range(len(Y)):
            if col[i][j] == 1 and inblock(i,j) == 0:
                x1.append(X[i])
                y1.append(Y[j])
    point_ani.set_marker("o")
    
    point_ani.set_markersize(10)
    
    point_ani.set_data(x1,y1)
    
    # point_ani.set_color([ math.fabs(math.sin(2*np.pi*num/500)), math.fabs(math.cos(2*np.pi*num/500)), math.fabs(math.cos(2*np.pi*num/500+np.pi/2)) ])

    _col = copy.deepcopy(col)
    for i in  range(len(X)):
        for j in range(len(Y)):
            # print('(',i,j,')')
            for k in range(0,8):
                tx = i + dx[k]*np.random.randint(0,int(3*(500-num)/500.0)+1)
                ty = j + dy[k]*np.random.randint(0,int(3*(500-num)/500.0)+1)
                # print('tx=',tx,' ty=',ty)
                if tx >= 0 and tx < SZ and ty >= 0 and ty < SZ and inblock(tx,ty) == 0:
                    if _col[tx][ty] != _col[i][j]:
                        # print('colt = ',_col[tx][ty], 'coli = ', _col[i][j])
                        col[i][j] = _col[tx][ty]
                        if np.random.random() < 0.4 :
                            col[i][j] = 1 - col[i][j]
                        break
            
    return point_ani,


col = [[0 for i in range(SZ)] for i in range(SZ)]

# col[int(SZ/2)][int(SZ/2)] = 1

# col[0][0] = 1
# col[SZ-1][SZ-1] = 1
# col[int(SZ/2)][int(SZ/2)] = 1

for i in range(SZ):
    col[int(SZ/2)][i] = 1

X = np.linspace(0, 1, SZ)
Y = X
print(len(X),len(Y))

fig = plt.figure(tight_layout=True)
plt.xlim(-0.1,1.1)
plt.ylim(-0.1,1.1)
for x in X:
    for y in Y:
        plt.plot(x,y,'ok',6)

for i in range(SZ):
    for j in range(SZ):
        if inblock(i,j):
            plt.plot(X[i],Y[j],'or',6)

point_ani, = plt.plot(X, Y, 'ok')
# 开始制作动画
ani = animation.FuncAnimation(fig, update_points, np.arange(0,20), interval=20, blit=True)

# ani.save('test51_center.gif', writer='imagemagick', fps=10)
plt.show()
